RegDACLThe Permissions Manager for Registry keys
A "must have" for the clever Windows NT Administrator
Version 5.0 and 6.0
Help file - A crash course in Windows NT Registry permissions
Copyright © 1999-2001 Frank Heyne (fh@heysoft.de) - All rights reserved!
Part 2 - Tutorials
Last changed: 08. January 2001


Tutorial 1 - How different inheritance flags effect child keys
All the different inheritance options were already explained with the command /L. The following table summarizes all the possible options. It is essential to understand the differences between Windows NT until version 4 and later versions: In the following table the inheritance flag (ID) is missing, because it does not affect the validity of the ACEs, but tell you and Windows whether it is an inherited or an explicitly set ACE.
 
Inheritance flags ACE is valid for
current childs grandchilds
(CI) yes yes yes
(CI NP) yes yes no
(NI) yes no no
(IO) no yes yes
(IO NP) no yes no
We can test the effects of all inheritance options with this (not so useful) example. To learn more about the differences between the Windows versions, compare it with the Windows NT 4.0 example.
First, make sure that there exists a Registry key hklm\Software\Test, but there is no Registry key hklm\Software\Test\Demo on your Windows 2000 machine before running the following script Demo1.cmd:
 
@echo ### Check permissions for parent key hklm\Software\Test: 
RegDACL hklm\Software\Test /l 

@echo ### Create a new Registry path: 
reg add hklm\Software\Test\Demo\Child1\a=1 

@echo ### Check permissions for hklm\Software\Test\Demo\Child1: 
RegDACL hklm\Software\Test\Demo\Child1 /l /e 

@echo ### Set permissions for hklm\Software\Test\Demo: 
RegDACL hklm\Software\Test\Demo /sge:Q(ni) /sga:F(ci) /sgs:RWO(io) /sgi:r(ci-np) /sgn:qw(io-np) 

@echo ### Check new permissions for hklm\Software\Test\Demo: 
RegDACL hklm\Software\Test\Demo /l /e 

@echo ### Check permissions for hklm\Software\Test\Demo\Child1: 
RegDACL hklm\Software\Test\Demo\Child1 /l 

@echo ### Create a new Registry path: 
reg add hklm\Software\Test\Demo\Child2\Grandchild2\a=1 

@echo ### Check permissions for hklm\Software\Test\Demo\Child2: 
RegDACL hklm\Software\Test\Demo\Child2 /l 

@echo ### Check permissions for hklm\Software\Test\Demo\Child2\Grandchild2: 
RegDACL hklm\Software\Test\Demo\Child2\Grandchild2 /l

Running this script should result in the following output:
 
1 
2
C:\Reg> Demo1 
### Check permissions for parent key hklm\Software\Test:
3 
4 
5
Access Control List for Registry key "hklm\Software\Test": 
(CI)    ALLOW  Full access      BUILTIN\Administrators 
(CI)    ALLOW  Full access      NT AUTHORITY\SYSTEM
6 ### Create a new Registry path:
7 
8
C:\Reg> reg add hklm\Software\Test\Demo\Child1\a=1 
The operation completed successfully. 
9 ### Check permissions for hklm\Software\Test\Demo\Child1:
10 C:\Reg> RegDACL hklm\Software\Test\Demo\Child1 /l /e 
11 
12 
13
Access Control List for Registry key "hklm\Software\Test\Demo\Child1": 
(ID-CI) ALLOW  Full access      BUILTIN\Administrators 
(ID-CI) ALLOW  Full access      NT AUTHORITY\SYSTEM
14 
15 
16
Effective permissions for Registry key "hklm\Software\Test\Demo\Child1": 
Full access    BUILTIN\Administrators 
Full access    NT AUTHORITY\SYSTEM
17 ### Set permissions for hklm\Software\Test\Demo:
18 C:\Reg> RegDACL hklm\Software\Test\Demo /sge:Q(ni) /sga:F(ci) /sgs:RWO(io) /sgi:r(ci-np) /sgn:qw(io-np)
19 
20
Setting Q(NI) permissions for really "Everyone" 
 - adding new entry
21 
22 
23
Setting F(CI) permissions for predefined group "Administrators" 
 - adding new entry 
Warning: There is an inherited ACE for this account which will not be changed!
24 
25 
26
Setting RWO(IO) permissions for predefined group "System" 
 - adding new entry 
Warning: There is an inherited ACE for this account which will not be changed!
27 
28
Setting R(CI-NP) permissions for predefined group "Interactive" 
 - adding new entry 
29 
30
Setting QW(IO-NP) permissions for predefined group "Network" 
 - adding new entry 
31 ### Check new permissions for hklm\Software\Test\Demo: 
32 C:\Reg> RegDACL hklm\Software\Test\Demo /l /e
33 
34 
35 
36 
37 
38 
39 
40
Access Control List for Registry key "hklm\Software\Test\Demo": 
(NI)    ALLOW  Q---------       Everyone 
(CI)    ALLOW  Full access      BUILTIN\Administrators 
(IO)    ALLOW  QW-EN--S-O       NT AUTHORITY\SYSTEM 
(CI-NP) ALLOW  Read             NT AUTHORITY\INTERACTIVE 
(IO-NP) ALLOW  QW--------       NT AUTHORITY\NETWORK 
(ID-CI) ALLOW  Full access      BUILTIN\Administrators 
(ID-CI) ALLOW  Full access      NT AUTHORITY\SYSTEM
41 
42 
43 
44 
45
Effective permissions for Registry key "hklm\Software\Test\Demo": 
Q---------      Everyone 
Full access     BUILTIN\Administrators 
Read            NT AUTHORITY\INTERACTIVE 
Full access     NT AUTHORITY\SYSTEM
46 ### Check permissions for hklm\Software\Test\Demo\Child1:
47 C:\Reg> RegDACL hklm\Software\Test\Demo\Child1 /l 
48 
49 
50 
51 
52 
53
Access Control List for Registry key "hklm\Software\Test\Demo\Child1": 
(ID-CI) ALLOW  Full access      BUILTIN\Administrators 
(ID-CI) ALLOW  QW-EN--S-O       NT AUTHORITY\SYSTEM 
(ID-NI) ALLOW  Read             NT AUTHORITY\INTERACTIVE 
(ID-NI) ALLOW  QW--------       NT AUTHORITY\NETWORK 
(ID-CI) ALLOW  Full access      NT AUTHORITY\SYSTEM
54 ### Create a new Registry path:
55 
56
C:\Reg> reg add hklm\Software\Test\Demo\Child2\Grandchild2\a=1 
The operation completed successfully.
57 ### Check permissions for hklm\Software\Test\Demo\Child2: 
58 C:\Reg> RegDACL hklm\Software\Test\Demo\Child2 /l
59 
60 
61 
62 
63 
64
Access Control List for Registry key "hklm\Software\Test\Demo\Child2": 
(ID-CI) ALLOW  Full access      BUILTIN\Administrators 
(ID-CI) ALLOW  QW-EN--S-O       NT AUTHORITY\SYSTEM 
(ID-NI) ALLOW  Read             NT AUTHORITY\INTERACTIVE 
(ID-NI) ALLOW  QW--------       NT AUTHORITY\NETWORK 
(ID-CI) ALLOW  Full access      NT AUTHORITY\SYSTEM
65 ### Check permissions for hklm\Software\Test\Demo\Child2\Grandchild2:
66 C:\Reg> RegDACL hklm\Software\Test\Demo\Child2\Grandchild2 /l
67 
68 
69 
70
Access Control List for Registry key "hklm\Software\Test\Demo\Child2\Grandchild2": 
(ID-CI) ALLOW  Full access      BUILTIN\Administrators 
(ID-CI) ALLOW  QW-EN--S-O       NT AUTHORITY\SYSTEM 
(ID-CI) ALLOW  Full access      NT AUTHORITY\SYSTEM
Result of Tutorial 1 on a Windows NT 5 machine
Explanation of the result of Tutorial 1:
 
Lines 12 to 13 When creating a new key with the command reg (from the Resource Kit) we can't assign explicit permissions. The system inherits the DACL from its parent (lines 8 and 9) to the new key.
Lines 34 to 45 The permissions for Network are only valid for its descendants (IO), hence this group does not have any effective permissions for the key itself. The permissions for System in line 36 are only valid for its descendants (IO), but because of the inherited permissions in line 40 this group does have effective permissions for the key itself.
Lines 49 to 53 As expected, the permissions for this key were changed through propagation when the permissions for its parent were modified in lines 18 to 30.
Lines 60 to 64 Though this key was created after the  permissions for its parent were changed, it has exactly the same permissions as its sibling child1 which was created before the changes were made.
Lines 68 to 70 The permissions for this key were inherited from its parents permissions (lines 60 to 64). The entries for Administrators and System have not been changed. The ACEs for Interactiv and Network are not inheritable (NI) and thus are missing in the new key. You might wonder why both entries for System were not merged. Doing so would cause havoc when one of the origins of the ACEs would be removed, for this reason apparently redundant entries will never merge.


Tutorial 2 - The group CREATOR OWNER
This group is a very special thing, because it never will have a member. Windows 2000 handles it different from all other accounts, and different from earlier versions of Windows NT. Until Windows NT 4.0 this account applied to the CREATOR of an object, but in Windows 2000 it applies to the OWNER (at least mostly ;). The difference becomes only clear when you change the owner. Let's see what happens when we are logged on as Administrator and run the following commands:
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93
C:\Reg> RegOwner hklm\software\test /l -subtree 
RegOwner 1.0 - Owner manager for Registry keys 
Copyright (c) 1999-2000 Frank Heyne Software (http://www.heysoft.de)  

Owner of Registry keys: 
BUILTIN\Administrators  hklm\software\test 
TEST\PU                 hklm\software\test\subkey1  

C:\Reg> regdacl hklm\software\test /l -subtree  

Access Control List for Registry key "hklm\software\test": 
(CI)    ALLOW  Full access      BUILTIN\Administrators 
(IO)    ALLOW  QWCEN-DS--       CREATOR OWNER  

Access Control List for Registry key "hklm\software\test\Subkey1": 
(ID-CI) ALLOW  Full access      BUILTIN\Administrators 
(ID-NI) ALLOW  QWCEN-DS--       TEST\PU 
(ID-IO) ALLOW  QWCEN-DS--       CREATOR OWNER  

C:\Reg> regdacl hklm\software\test /sgo:r  

Setting R permissions for predefined group "Creator Owner" 
 - removing existing entry 
 - adding new entry  

C:\Reg> regdacl hklm\software\test /l -subtree  

Access Control List for Registry key "hklm\software\test": 
(CI)    ALLOW  Full access      BUILTIN\Administrators 
(NI)    ALLOW  Read             BUILTIN\Administrators 
(IO)    ALLOW  Read             CREATOR OWNER  

Access Control List for Registry key "hklm\software\test\Subkey1": 
(ID-CI) ALLOW  Full access      BUILTIN\Administrators 
(ID-NI) ALLOW  Read             TEST\PU 
(ID-IO) ALLOW  Read             CREATOR OWNER  

C:\Reg> RegOwner hklm\software\test\subkey1 /t 
RegOwner 1.0 - Owner manager for Registry keys 
Copyright (c) 1999-2000 Frank Heyne Software (http://www.heysoft.de)  

Taking ownership of hklm\software\test\subkey1  

C:\Reg> RegDACL hklm\software\test /l -subtree  

Access Control List for Registry key "hklm\software\test": 
(CI)    ALLOW  Full access      BUILTIN\Administrators 
(NI)    ALLOW  Read             BUILTIN\Administrators 
(IO)    ALLOW  Read             CREATOR OWNER  

Access Control List for Registry key "hklm\software\test\Subkey1": 
(ID-CI) ALLOW  Full access      BUILTIN\Administrators 
(ID-NI) ALLOW  Read             TEST\PU 
(ID-IO) ALLOW  Read             CREATOR OWNER  

C:\Reg> regdacl hklm\software\test /sgo:rwd  

Setting RWD permissions for predefined group "Creator Owner" 
 - removing existing entry 
 - adding new entry  

C:\Reg> RegDACL hklm\software\test /l -subtree  

Access Control List for Registry key "hklm\software\test": 
(CI)    ALLOW  Full access      BUILTIN\Administrators 
(NI)    ALLOW  Read             BUILTIN\Administrators 
(NI)    ALLOW  QW-EN-DS--       BUILTIN\Administrators 
(IO)    ALLOW  QW-EN-DS--       CREATOR OWNER  

Access Control List for Registry key "hklm\software\test\Subkey1": 
(ID-CI) ALLOW  Full access      BUILTIN\Administrators 
(ID-NI) ALLOW  QW-EN-DS--       TEST\Administrator 
(ID-IO) ALLOW  QW-EN-DS--       CREATOR OWNER  

C:\Reg> regdacl hklm\software\test /sgo:rw  

Setting RW permissions for predefined group "Creator Owner" 
 - removing existing entry 
 - adding new entry  

C:\Reg> RegDACL hklm\software\test /l -subtree  

Access Control List for Registry key "hklm\software\test": 
(CI)    ALLOW  Full access      BUILTIN\Administrators 
(NI)    ALLOW  Read             BUILTIN\Administrators 
(NI)    ALLOW  QW-EN-DS--       BUILTIN\Administrators 
(NI)    ALLOW  QW-EN--S--       BUILTIN\Administrators 
(IO)    ALLOW  QW-EN--S--       CREATOR OWNER  

Access Control List for Registry key "hklm\software\test\Subkey1": 
(ID-CI) ALLOW  Full access      BUILTIN\Administrators 
(ID-NI) ALLOW  QW-EN--S--       TEST\Administrator 
(ID-IO) ALLOW  QW-EN--S--       CREATOR OWNER

Result of Tutorial 2
Explanation of the results of Tutorial 2:
Lines 1 to 7 We check the current owners of hklm\software\test with RegOwner, which comes as part of the registered version of RegTools for Windows NT. The owner for the parent key is group Administrators, while the owner for the child is power user PU from our machine TEST. 
Lines 11 to 18 We check the current permissions for the tree we want to play with. The parent hklm\software\test is protected against inheriting permissions from parents, while its only subkey is not. These DACLs were constructed for the tutorial by deleting unnecessary ACEs. 
We see that there are always only (IO) ACEs for CREATOR OWNER. Let us check what happens when we try to change these settings.
Lines 20 to 24 We change the permissions for CREATOR OWNER of the parent key to Read. Because we specified no inheritance flags, RegDACL defaults to (CI).
Lines 28 to 36 The result is baffling - we changed ACEs for CREATOR OWNER, Administrators and PU. What did Windows 2000? It splitted the single new (CI) ACE into two ACEs - an (NI) ACE for the current owner of every key as well as an (IO) ACE for CREATOR OWNER.So we have really no chance creating a (NI) ACE for  CREATOR OWNER - the operating system will always apply this ACE to the current owner of an object.
Lines 38 to 42 Now we take ownership of the child key with RegOwner.
Lines 44 to 54 Did taking ownership change anything in the DACL of the key? 
No, line 53 shows still an ACE for the former owner, while there is no entry for the new owner Administrator. 
This looks more like a bug than a feature in Windows 2000.
Lines 56 to 60 Again, we change the permissions for CREATOR OWNERof the parent key.
Lines 64 to 73 The result for the subkey is surprising - Only now (and not as expected after the command in line 38) the ACE for the former owner PU was replaced with an ACE for the current owner of the subkey.
Lines 75 to 79 Again, we change the permissions for CREATOR OWNERof the parent key.
Lines 83 to 93 All works as expected - except one annoying thing: The ACE in line 87 was created, though there is already an ACE for the current owner of this key in line 86. But how should Windows know that this entry in line 86 was not created directly for Administrator, but for the owner? Therefore it creates a new (and totally redundant) entry for the current owner. We learn here that it is a good practice to apply ACEs for CREATOR OWNER always only with the (IO) flag, otherwise the results might be unexpected! At least until Microsoft supplements the inheritance flags with the flag which was forgotten when designing Windows 2000 - one for marking ACEs of owners.
Annotation: RegEdt32 tries (partly successfully) to circumvent both bugs demonstrated here through arbitrary changes of the settings made by the user. With the second bug (creating a redundant entry in line 87) this method succeeds, but not with the first bug (missing to change of the owner in line 53). For this reason we assume Microsoft will introduce a flag marking the ACE of the owner in one of the next versions of Windows NT. That's why RegDACL renounces to domineer over the user - it does not arbitrarily change his or her settings.

 


Tutorial 3 - Sort order of ACEs within an Access Control List
There is another surprise in Windows 2000. Let run the following script:
reg delete hklm\software\test
reg add hklm\software\test\a\b\c\w=1
RegDACL hklm\software\test /sga:f /dgn:c
RegDACL hklm\software\test /pr
RegDACL hklm\software\test\a /sgn:q /dgn:w
RegDACL hklm\software\test\a\b /sgn:e /dgn:a
RegDACL hklm\software\test\a\b\c /sgn:n /dgn:o
RegDACL hklm\software\test\a\b\c /l
The last command delivers the following output:
Access Control List for Registry key "hklm\software\test\a\b\c":
(CI)    DENY   ---------O      NT AUTHORITY\NETWORK
(CI)    ALLOW  ----N-----      NT AUTHORITY\NETWORK
(ID-CI) DENY   --------A-      NT AUTHORITY\NETWORK
(ID-CI) ALLOW  ---E------      NT AUTHORITY\NETWORK
(ID-CI) DENY   -W--------      NT AUTHORITY\NETWORK
(ID-CI) ALLOW  Q---------      NT AUTHORITY\NETWORK
(ID-CI) DENY   --C-------      NT AUTHORITY\NETWORK
(ID-CI) ALLOW  Full access     BUILTIN\Administrators
It looks like DENY and ALLOW entries are not sorted at all. But it is really all ok. When somebody is trying to access a protected object, its access control list will be checked from top downwards until either all requested permissions are granted (= access allowed) or at least one of the requested permissions is denied (= access denied). When all entries are checked and still not all requested permissions are granted, access will be denied, too.
Explicitely defined permissions for an object overwrite inherited permissions. That means they must be on top of the list. ACEs inherited from a parent overwrite ACEs inherited from a grandparent, and so on. With this in mind, the list above is very well sorted:
  1. The first two entries are explicit for the object.
  2. The next entries are inherited from the parent.
  3. The 5th and 6th entry are inherited from the grandparent.
  4. The first two entries are inherited from the parent's  grandparent.
Within every "inheritance layer" all DENY entries are sorted before the ALLOW entries. 

Is everything clear now?
When you have read this document carefully and you still have a question or are vague regarding a topic, you can email to fh@heysoft.de. But please check first the Security FAQ for the Windows NT Registry - your question might be already answered there. If you find errors or would like to contribute knowledge to this document, you are encouraged to email us, too.
When your mother tongue is not English or German, you can translate this documentation into your native language and get a registered version of RegTools for free (but you need to ask first, before you start, in case somebody else is working on the same project!)